from common.log.log_config import logger
from config.cluster_config_new import ClusterPrometheusClient
from config.prometheus_metric import PrometheusMetric
QUERY_STEP = 300


# 获取节点的down(up==0)的数据，间隔QUERY_STEPs
def getNodeDownInfo(prometheusClient: ClusterPrometheusClient, start: int, end: int) -> dict:
        return prometheusClient.query_range(PrometheusMetric.NODES_DOWN, start, end, QUERY_STEP)


# 获取容器的信息
def getContainerDict(prometheusClient: ClusterPrometheusClient, start: int, end: int) -> dict:
    return prometheusClient.query_range(PrometheusMetric.PODS_DEV_UTIL, start, end, QUERY_STEP)


def getNodeDownIp(prometheusClient: ClusterPrometheusClient, start, end):
    dictUp = getNodeDownInfo(prometheusClient, start, end)
    metrics = dictUp['data']['result']
    listDown = []
    for metric in metrics:
        down = {}
        down['instance'] = metric['metric']['instance']
        down['rqtime'] = list(value[0] for value in metric['values'])
        listDown.append(down)
    return listDown


# 过滤badinstances的节点数据
def checkNodes(listDown):
    # 目前需要通过自定义方式
    checkedDown = []
    for down in listDown:
            checkedDown.append(down)
    return checkedDown


def findRanges(listDown):
    downInfos = []
    logger.info("listDown is {}".format(listDown))
    for down in listDown:
        rqtime = down['rqtime']
        start = end = rqtime[0]
        for value in rqtime:
            if start != end and (value - end) != QUERY_STEP:
                downInfos.append(dict(instance=down["instance"],
                    start=start*1000,
                    end=end*1000))
                start = value
            # 最后一个元素
            elif value == rqtime[-1]:
                downInfos.append(dict(instance=down["instance"],
                    start = start*1000,
                    end = value*1000 ))
            end = value

    return downInfos


def getContainerInfo(prometheusClient, start, end):
    dictContaner = getContainerDict(prometheusClient, start, end)
    metrics = dictContaner['data']['result']
    containerInfos = []
    for metric in metrics:
        containerInfo = {}
        values = list(value[0] for value in metric['values'])
        containerInfo['instance'] = metric['metric'].get('node_name', "")
        containerInfo['jobname'] = metric['metric'].get('taskset_name', "")
        containerInfo['start'] = min(values)*1000
        containerInfo['end'] = max(values)*1000
        containerInfo['usrname'] = metric['metric'].get('username', "")
        containerInfo['taskindex'] = metric['metric'].get('taskset_role_index', "")
        containerInfo['taskrolename'] = metric['metric'].get('taskset_role')
        containerInfos.append(containerInfo)
    return containerInfos


def checkContainerInfo(downInfos, containerInfos):
    for downInfo in downInfos:
        containers = []
        for containerInfo in containerInfos:
            if containerInfo['instance'] == downInfo['instance']\
               and containerInfo['end'] >= (downInfo['start']- 5*60*1000) \
               and containerInfo['end'] <= (downInfo['start']+ 5*60*1000):
                containers.append(containerInfo)
        downInfo['containers'] = containers
    return downInfos


def findContainerInfo(prometheusClient, start: int, end: int):
    listDown = getNodeDownIp(prometheusClient, start, end)
    checkedDown = checkNodes(listDown)
    downInfos = findRanges(checkedDown)
    logger.info(downInfos)
    containerInfos = getContainerInfo(prometheusClient, start, end)
    logger.info(containerInfos)
    downContainerInfos = checkContainerInfo(downInfos, containerInfos)
    logger.info(downContainerInfos)

    return downContainerInfos


